package edu.ntnu.superrss.utils.feedgrabber;

import java.net.URL;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

/**
 * While running, spawns new UrlWorkers with elements from its queue.
 * Singelton Pattern. Only one queue instance allowed.
 * 
 * @author sigurd
 */
public class UrlQueue implements Runnable {

	private int threads;
	private BlockingQueue<URL> urlQueue;
	private static UrlQueue instance = null;

	private UrlQueue() {
		//prevent construction
		this.threads = 10;
		urlQueue = new LinkedBlockingDeque();
		Thread t = new Thread(this);
		t.start();
	}

	/**
	 *
	 * Factory Method, Singelton Pattern.
	 * @return a instance of UrlQueue
	 */
	public synchronized static UrlQueue getInstance() {
		if (instance == null) {
			instance = new UrlQueue();
		}
		return instance;
	}
	/**
	 * Never ending loop that executes UrlWorkers with urls from the queue
	 */
	public void run() {
		Executor executer = Executors.newFixedThreadPool(threads);
		while (true) {
			try {
				URL url = urlQueue.take();
				executer.execute(new UrlWorker(url));
			} catch (InterruptedException ie) {
				System.err.println("Interrupted " + ie); //TODO: LOG4J
			}
		}
	}
	/**
	 * Adds a url to this queue, if it is possible to do so immediately.
	 */
	public boolean add(URL e) {
		return urlQueue.add(e);
	}
	/**
	 * Retrieves and removes the head of this queue, waiting if no elements are present on this queue.
	 * @throws InterruptedException
	 */
	public URL take() throws InterruptedException {
		return urlQueue.take();
	}

	
	/**
	 * Clears the queue
	 */
	public void clear() {
		urlQueue.clear();
	}
}
